#ifndef __DISPATCHER_H_
#define __DISPATCHER_H_

#include <list>
#include <queue>
#include <mutex>
#include <condition_variable>


class CallRequest
{
public:
	CallRequest() {}
	virtual ~CallRequest(void) {}
	
	virtual int Call(void *args) = 0;
};

class MessageRequest: public CallRequest
{
public:

	MessageRequest(int type);

	~MessageRequest(void);

	virtual int Call(void *args);

	int GetType(void) const;

	int ExtType(void) const;

	void ExtType(int type);

	virtual bool DelayRelease() {return false;}

private:
	int msg_type_;
	int ext_type_;
};

class MessageQueue
{
public:
	MessageQueue();
	~MessageQueue();

	typedef std::queue<MessageRequest *> msg_request_queue_t;
	
	int Put(MessageRequest *req);
	MessageRequest *Get();

private:
	msg_request_queue_t msg_queue_;
	std::condition_variable cv_; 
	std::mutex mutex_; 
};

class MessageDeliver
{
public:
	MessageDeliver(int type);
	virtual ~MessageDeliver(void);
	
	enum
	{
		MSG_TYPE_NONE = 0,

		MSG_TYPE_SIGNAL,

		MSG_TYPE_CONFIG
	};
  
	int GetType(void) const;
	void SetType(int type);

	int Work(MessageRequest *mr);

	virtual int Execute(void *args) = 0;

private:
	static void *GetRequest(void* arg);

private:
	MessageQueue *queue_;
	int type_;
};

class MessageDispatcher 
{  
public:
	MessageDispatcher(void);
	~MessageDispatcher(void);

	int RegisterCommDeliver(MessageDeliver *deliver_ptr);

	int UnRegisterCommDeliver(MessageDeliver *deliver_ptr);

	int DispatchMsg(MessageRequest *msg_req);

	static MessageDispatcher* Instance();

private:
	int DispatchCommMsg(MessageRequest *msg_req);

	typedef std::list<MessageDeliver *> msg_deliver_list_t;

	typedef std::list<MessageDeliver *>::iterator msg_deliver_list_iter_t;

private:
	static MessageDispatcher * m_pInstance;
	msg_deliver_list_t comm_msg_deliver_list_;
	std::mutex lock_;
};

#endif

